home *** CD-ROM | disk | FTP | other *** search
/ Emulator Universe CD / emulatoruniversecd1998.iso / CPC / Utils / CpcFile System / DOS.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-02-08  |  18.1 KB  |  704 lines

  1.  
  2. /*                <<<<Last Modified: Thu Feb 08 15:07:42 1996>>>>
  3. ------------------------------------------------------------------------------
  4.  
  5.     =====
  6.     CPCfs  --  d o s . c   ---   Borland C specific routines
  7.     =====
  8.  
  9.     Version 0.85                    (c) February '96 by Derik van Zuetphen
  10. ------------------------------------------------------------------------------
  11. */
  12.  
  13.  
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include <dir.h>
  17. #include <dos.h>    /* the one in includedir of course */
  18.  
  19. #include "cpcfs.h"
  20.  
  21. #define min(A,B)    ((A)<=(B)?(A):(B))
  22. extern char Break_Wish;
  23.  
  24. char    cwdbuffer[256];
  25.  
  26.  
  27. int break_handler() {
  28.     Break_Wish = 1; /*TRUE*/;
  29.     return 1;   /* 0 = exit(); 1 = continue program */
  30. }
  31.  
  32. void disable_break() {
  33.     ctrlbrk(break_handler);
  34. }
  35.  
  36.  
  37. char wait_for_key (int must_be_0, char must_be_TRUE) {
  38. /*   ^^^^^^^^^^^^ */
  39. char    c;
  40.     while (!kbhit()) ;
  41.     if((c=getch())==0)
  42.         return getch();
  43.     else
  44.         return c;
  45. } /*wait_for_key*/
  46.  
  47. int    saved_drive;
  48. char    saved_path[MAXPATH];
  49.  
  50. void save_path () {
  51. /*   ^^^^^^^^^
  52. Saves current drive and directory path */
  53.     saved_drive = getdisk();
  54.     getcwd(saved_path,MAXPATH);
  55. }
  56.  
  57. void rest_path () {
  58. /*   ^^^^^^^^^
  59. Restores saved drive and directory path */
  60.     setdisk(saved_drive);
  61.     chdir(saved_path);
  62. }
  63.  
  64.  
  65. struct ffblk glob_buffer;
  66. char    glob_dir[MAXPATH];
  67.  
  68. char *glob_file (char *pattern) {
  69. /*    ^^^^^^^^^ */
  70. static char
  71.     n[MAXPATH];
  72. char    drive[MAXDRIVE];
  73. char    dir[MAXDIR];
  74. char    name[MAXFILE];
  75. char    ext[MAXEXT];
  76. int    flags;
  77.  
  78.     flags=fnsplit(pattern,drive,dir,name,ext);
  79.     *glob_dir=0;
  80.     if (DRIVE & flags) {
  81.         strcpy(glob_dir,drive);
  82.         strcat(glob_dir,":");
  83.     }
  84.     if (DIRECTORY & flags) {
  85.         strcat(glob_dir,dir);     /* included trailing "\" */
  86.     }
  87.  
  88.     if (findfirst(pattern,&glob_buffer,0)) {
  89.         return NULL;
  90.     }
  91.     strcpy(n,glob_dir); strcat(n,glob_buffer.ff_name);
  92.     return n;
  93. }
  94.  
  95.  
  96. char *glob_next () {
  97. /*    ^^^^^^^^^ */
  98. static char
  99.     n[MAXPATH];
  100.  
  101.     if (findnext(&glob_buffer)) {
  102.         return NULL;
  103.     }
  104.     strcpy(n,glob_dir); strcat(n,glob_buffer.ff_name);
  105.     return n;
  106. }
  107.  
  108.  
  109. char* tmp_nam(char* buf) {
  110. /*    ^^^^^^^
  111. Calls tmpnam() and prepends the value of the %TEMP environment variable.
  112. Contrary to tmpnam(), <buf> must not be NULL! */
  113. char    *temp;
  114. char    name[INPUTLEN];
  115.  
  116.     temp = getenv("TEMP");
  117.     if (temp==NULL)    strcpy(buf,".");
  118.     else        strcpy(buf,temp);
  119.     if (temp[strlen(temp)]!='\\') strcat(buf,"\\");
  120.     tmpnam(name);
  121.     strcat(buf,name);
  122.     return buf;
  123. }
  124.  
  125.  
  126. void os_init() {
  127. /*   ^^^^^^^
  128. Nothing to do for DOS */
  129. }
  130.  
  131.  
  132. /**********************************************************************
  133.                 History
  134.  **********************************************************************/
  135.  
  136. #define MaxHistSize 100
  137.  
  138. int    hist_size = 0;  /* number of entries in history */
  139. int    hist_last = 0;  /* number of last entered entry */
  140. char    *history[MaxHistSize];    /* filled with NULLS */
  141.  
  142. int add_history(char *line) {
  143. /*  ^^^^^^^^^^^
  144. Add <line> to the history list */
  145. char    *str;
  146.  
  147.     str = (char*)Malloc(strlen(line)+1);
  148.     strcpy(str,line);
  149.     if (hist_size < MaxHistSize) {        /* append */
  150.         history[hist_size] = str;
  151.         hist_last = hist_size++;
  152.     } else {                       /* overwrite eldest entry */
  153.         hist_last = (hist_last+1) % MaxHistSize;
  154.         free(history[hist_last]);
  155.         history[hist_last] = str;
  156.     }
  157.     return 0;
  158. }
  159.  
  160. /**********************************************************************
  161.     The next lines in this file are insertions from ACTlib 1.7
  162.     (slightly modified)
  163.     former name: KEY.H
  164.  **********************************************************************/
  165. /*
  166.  *  Copyright (C) 1993   Marc Stern  (internet: stern@mble.philips.be)
  167.  *
  168.  * File         : key.h
  169.  *
  170.  * Description  : key code definitions.
  171.  *
  172.  */
  173.  
  174.  
  175. #ifndef __Key_H
  176. #define __Key_H
  177.  
  178.  
  179. #define RETURN            0x0d
  180. #define ENTER                   RETURN
  181. #define SPACE            0x20
  182. #define ESC            0x1b
  183. #define BKSP            0x08
  184. #define BACKSPACE        0x08
  185.  
  186. #define UP                  328
  187. #define DOWN                    336
  188. #define LEFT                    331
  189. #define RIGHT                   333
  190. #define PGUP                329
  191. #define PGDN                    337
  192. #define HOME                    327
  193. #define END                         335
  194. #define INSERT                        338
  195. #define INS                     INSERT
  196. #define DELETE                        339
  197. #define DEL                     DELETE
  198.  
  199. enum { F1 = 315, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11 = 389, F12 };
  200.  
  201. #define CTRL_UP                  397
  202. #define CTRL_DOWN               401
  203. #define CTRL_LEFT               371
  204. #define CTRL_RIGHT              372
  205. #define CTRL_PGUP        388
  206. #define CTRL_PGDN            374
  207. #define CTRL_HOME               375
  208. #define CTRL_END                 373
  209. #define CTRL_INSERT             402
  210. #define CTRL_INS                CTRL_INSERT
  211. #define CTRL_DELETE             403
  212. #define CTRL_DEL                CTRL_DELETE
  213.  
  214. enum { CTRL_F1 = 350, CTRL_F2, CTRL_F3, CTRL_F4, CTRL_F5,
  215.        CTRL_F6, CTRL_F7, CTRL_F8, CTRL_F9, CTRL_F10,
  216.        CTRL_F11 = 393, CTRL_F12
  217.      };
  218.  
  219. #define CTRL_A                  1
  220. #define CTRL_B                  2
  221. #define CTRL_C                  3
  222. #define CTRL_D                  4
  223. #define CTRL_E                  5
  224. #define CTRL_F                  6
  225. #define CTRL_G                  7
  226. #define CTRL_H                  8
  227. #define CTRL_I                  9
  228. #define CTRL_J                  10
  229. #define CTRL_K                  11
  230. #define CTRL_L                  12
  231. #define CTRL_M                  13
  232. #define CTRL_N                  14
  233. #define CTRL_O                  15
  234. #define CTRL_P                  16
  235. #define CTRL_Q                  17
  236. #define CTRL_R                  18
  237. #define CTRL_S                  19
  238. #define CTRL_T                  20
  239. #define CTRL_U                  21
  240. #define CTRL_V                  22
  241. #define CTRL_W                  23
  242. #define CTRL_X                  24
  243. #define CTRL_Y                  25
  244. #define CTRL_Z                  26
  245.  
  246. #define ALT_UP                  408
  247. #define ALT_DOWN                416
  248. #define ALT_LEFT                411
  249. #define ALT_RIGHT               413
  250. #define ALT_PGUP            409
  251. #define ALT_PGDN            417
  252. #define ALT_HOME                407
  253. #define ALT_END                 415
  254. #define ALT_INSERT              418
  255. #define ALT_INS                 ALT_INSERT
  256. #define ALT_DELETE              419
  257. #define ALT_DEL                 ALT_DELETE
  258.  
  259. enum { ALT_F1 = 360, ALT_F2, ALT_F3, ALT_F4, ALT_F5,
  260.        ALT_F6, ALT_F7, ALT_F8, ALT_F9, ALT_F10,
  261.        ALT_F11 = 395, ALT_F12
  262.      };
  263.  
  264. #define ALT_A                   286
  265. #define ALT_B                   304
  266. #define ALT_C                   302
  267. #define ALT_D                   288
  268. #define ALT_E                   274
  269. #define ALT_F                   289
  270. #define ALT_G                   290
  271. #define ALT_H                   291
  272. #define ALT_I                   279
  273. #define ALT_J                   292
  274. #define ALT_K                   293
  275. #define ALT_L                   294
  276. #define ALT_M                   306
  277. #define ALT_N                   305
  278. #define ALT_O                   280
  279. #define ALT_P                   281
  280. #define ALT_Q                   272
  281. #define ALT_R                   275
  282. #define ALT_S                   287
  283. #define ALT_T                   276
  284. #define ALT_U                   278
  285. #define ALT_V                   303
  286. #define ALT_W                   273
  287. #define ALT_X                   301
  288. #define ALT_Y                   277
  289. #define ALT_Z                   300
  290.  
  291. #define SHIFT_UP                  328
  292. #define SHIFT_DOWN              336
  293. #define SHIFT_LEFT              331
  294. #define SHIFT_RIGHT             333
  295. #define SHIFT_PGUP            329
  296. #define SHIFT_PGDN            337
  297. #define SHIFT_HOME              327
  298. #define SHIFT_END               335
  299. #define SHIFT_INSERT            338
  300. #define SHIFT_INS               SHIFT_INSERT
  301. #define SHIFT_DELETE                339
  302. #define SHIFT_DEL               SHIFT_DELETE
  303.  
  304. enum { SHIFT_F1 = 340, SHIFT_F2, SHIFT_F3, SHIFT_F4, SHIFT_F5,
  305.        SHIFT_F6, SHIFT_F7, SHIFT_F8, SHIFT_F9, SHIFT_F10,
  306.        SHIFT_F11 = 391, SHIFT_F12
  307.      };
  308.  
  309. #endif
  310.  
  311.  
  312. /**********************************************************************
  313.     former name: INPUTS.C (history access added)
  314.  **********************************************************************/
  315.  
  316. /*  Copyright (C) 1993   Marc Stern  (internet: stern@mble.philips.be)   */
  317.  
  318. #include <conio.h>
  319. #include <string.h>
  320. #include <stdlib.h>
  321. #include <time.h>
  322.  
  323. #define True      1
  324. #define False    0
  325.  
  326. int insert_mode = True;
  327.  
  328.  
  329. /***
  330.  *  Function    :   inputs
  331.  *
  332.  *  Description :   Input a string from keyboard
  333.  *
  334.  *  Parameters  :   in/out   char * data        default and result
  335.  *                  in       int    maxLen      maximum length to accept
  336.  *                  in       int    timeout     maximum time (seconds) waiting
  337.  *                                              before a key is pressed
  338.  *
  339.  *
  340.  *  Decisions   :   Valid keys:   Home         Begin of line
  341.  *                          End          End of line
  342.  *                                Left/Right   One character left/right
  343.  *                  Up/Down      Browse thru history
  344.  *                          Insert       Toggle insert on/off
  345.  *                                Delete       Delete current  character
  346.  *                                BackSpace    Delete previous character
  347.  *                          Ctrl-home    Erase to begin-of-line
  348.  *                          Ctrl-end     Erase to end-of-line
  349.  *                                Escape       Erase whole input
  350.  *                                Enter        Accept input
  351.  *            plus EMACS bindings
  352.  *
  353.  *                  Default string is erase if another input is given.
  354.  *                  (if any non-editing character is hit).
  355.  *
  356.  *                  If no key is hit before timeout (in seconds)
  357.  *                  the function returns.
  358.  *                  timeout -1 means no timeout.
  359.  *                  timeout  0 means check for type-ahead.
  360.  *
  361.  *  Return      :   length of input
  362.  *                  -1 if time-out
  363.  *                  -2 if Ctrl-Z
  364.  *
  365.  *  OS/Compiler :   MS-DOS & Turbo-C
  366.  ***/
  367.  
  368. int inputs( char *data, int maxLen, int timeout )
  369. {
  370.  int Xpos = wherex(), Ypos = wherey(), len = strlen( data ), oldLen = 0;
  371.  char *curPos = data + len;
  372.  int firstkey = True, x, y, c;
  373.  struct text_info ti;
  374.  int hist = -1;            /* not in history yet */
  375.  char hist_used = False;        /* flag to signify line redraw */
  376.  
  377.  gettextinfo( &ti );
  378.  
  379.  for (;;)
  380.     {
  381.      if ( hist_used || len != oldLen )
  382.     {
  383.      hist_used = False;
  384.      gotoxy( Xpos, Ypos );
  385.      cputs( data );
  386.      for ( ; oldLen > len; oldLen-- ) cputs(" ");
  387.      if ( oldLen < len ) oldLen = len;
  388.      Ypos = min( Ypos, wherey() - (Xpos + len - 1) / ti.screenwidth );
  389.     }
  390.  
  391.      if ( firstkey && (timeout >= 0) )
  392.     {
  393.      time_t now = time( NULL );  /* Gets system time */
  394.  
  395.      do if ( kbhit() ) timeout = -1;
  396.      while ( difftime(time(NULL), now) < timeout );
  397.  
  398.      if ( timeout >= 0 ) return -1;
  399.     }
  400.  
  401.  _setcursortype( insert_mode ? _NORMALCURSOR : _SOLIDCURSOR );
  402.  
  403. #pragma warn -sig
  404.      for ( x = curPos - data + Xpos, y = Ypos;
  405.        x > ti.screenwidth;
  406.        x -= ti.screenwidth, y++
  407.      );
  408.      gotoxy( x, y );
  409. #pragma warn .sig
  410.  
  411.      switch( c = getkey() )
  412.      {
  413.       case LEFT:
  414.       case CTRL_B:
  415.      if ( curPos > data ) curPos--;
  416.      break;
  417.  
  418.       case RIGHT:
  419.       case CTRL_F:
  420.      if ( curPos < data + len ) curPos++;
  421.      break;
  422.  
  423.       case UP:
  424.       case CTRL_P:
  425.      if (hist==-1) hist = hist_last;
  426.      else          {hist--; hist = (hist<0? hist_size-1 : hist);}
  427.      strcpy(data,history[hist]);
  428.      len = strlen(data);
  429.      curPos = data+len;
  430.      hist_used = True;
  431.      break;
  432.  
  433.      case DOWN:
  434.      case CTRL_N:
  435.      if (hist==-1) break;
  436.      else          hist = (hist+1)%hist_size;
  437.      strcpy(data,history[hist]);
  438.      len = strlen(data);
  439.      curPos = data+len;
  440.      hist_used = True;
  441.      break;
  442.  
  443.       case HOME:
  444.       case CTRL_A:
  445.      curPos =  data;
  446.      break;
  447.  
  448.       case END:
  449.       case CTRL_E:
  450.      curPos = data + len;
  451.      break;
  452.  
  453.       case BACKSPACE:
  454.      if ( curPos > data )
  455.         {
  456.          strcpy( curPos - 1, curPos );
  457.          curPos--;
  458.          len--;
  459.         }
  460.      break;
  461.  
  462.       case CTRL_D:
  463.       case DEL:
  464.      if ( curPos < data + len )
  465.         {
  466.          strcpy( curPos , curPos + 1 );
  467.          len--;
  468.         }
  469.      break;
  470.  
  471.       case INSERT:
  472.       case CTRL_V:
  473.      insert_mode = ! insert_mode;
  474.      _setcursortype( insert_mode ? _NORMALCURSOR : _SOLIDCURSOR );
  475.      continue; /* break; */
  476.  
  477.       case ESC :
  478.       case CTRL_U:
  479.      *data = '\0';
  480.      curPos = data;
  481.      len = 0;
  482.      break;
  483.  
  484.       case CTRL_Z:
  485.       case ENTER:
  486.      cputs( "\r\n" ); clreol();
  487.      _setcursortype( _NORMALCURSOR );
  488.      if (c==CTRL_Z) return -2;
  489.            else return len;
  490.  
  491.       case CTRL_END:
  492.       case CTRL_K:
  493.      *curPos = '\0';
  494.      len = strlen( data );
  495.      break;
  496.  
  497.       case CTRL_HOME:
  498.      strcpy( data , curPos );
  499.      curPos = data;
  500.      len = strlen( data );
  501.      break;
  502.  
  503.       default:
  504.      if ( c > 255 )
  505.         {
  506.          break;
  507.         }
  508.  
  509.          if ( firstkey )
  510.             {
  511.              *data = '\0';
  512.              curPos = data;
  513.              len = 0;
  514.              ungetch( c );
  515.              break;
  516.             }
  517.  
  518.          if ( ! insert_mode )
  519.             {
  520.              cprintf( "%c", c );
  521.              *curPos++ = c;
  522.              if ( curPos >= data + len )
  523.                 {
  524.                  *curPos = '\0';
  525.                  len++;
  526.                 }
  527.              break;
  528.             }
  529.  
  530.          if ( len == maxLen )
  531.             {
  532.          break;
  533.             }
  534.  
  535.          memmove( curPos + 1, curPos, strlen(curPos) + 1 );
  536.          *curPos++ = c;
  537.          len++;
  538.          break;
  539.       }
  540.  
  541.       firstkey = False;
  542.     }
  543. }
  544.  
  545.  
  546.  
  547. /**********************************************************************
  548.     former name: GETKEY.C
  549.  **********************************************************************/
  550.  
  551. /*  Copyright (C) 1993   Marc Stern  (internet: stern@mble.philips.be)  */
  552.  
  553. #include <conio.h>
  554.  
  555. /***
  556.  *
  557.  * Function   : getkey
  558.  *
  559.  * Description: return a 2-bytes key pressed
  560.  *              (extended characters are added to 256).
  561.  *
  562.  */
  563.  
  564. int getkey( void )
  565.  
  566. { int car;
  567.  
  568.  if ( ! (car = getch()) ) car = 256 + getch();
  569.  
  570.  return car;
  571. }
  572.  
  573. /**********************************************************************
  574.     The next lines of this file are insertions from Borland C++ 2.0
  575.     (slightly modified)
  576.     former name: GETOPT.C
  577.  **********************************************************************/
  578.  
  579. /*
  580.     Copyright (c) 1986,1991 by Borland International Inc.
  581.     All Rights Reserved.
  582. */
  583.  
  584. #include <errno.h>
  585. #include <string.h>
  586. #include <dos.h>
  587. #include <stdio.h>
  588.  
  589. int    optind    = 1;    /* index of which argument is next    */
  590. char   *optarg;        /* pointer to argument of current option */
  591. int    opterr    = 1;    /* allow error message    */
  592.  
  593. static    char   *letP = NULL;    /* remember next option char's location */
  594. static    char    SW = '-';    /* DOS switch character, either '-' or '/' */
  595.  
  596. /*
  597.   Parse the command line options, System V style.
  598.  
  599.   Standard option syntax is:
  600.  
  601.     option ::= SW [optLetter]* [argLetter space* argument]
  602.  
  603.   where
  604.     - SW is '-'
  605.     - there is no space before any optLetter or argLetter.
  606.     - opt/arg letters are alphabetic, not punctuation characters.
  607.     - optLetters, if present, must be matched in optionS.
  608.     - argLetters, if present, are found in optionS followed by ':'.
  609.     - argument is any white-space delimited string.  Note that it
  610.       can include the SW character.
  611.     - upper and lower case letters are distinct.
  612.  
  613.   There may be multiple option clusters on a command line, each
  614.   beginning with a SW, but all must appear before any non-option
  615.   arguments (arguments not introduced by SW).  Opt/arg letters may
  616.   be repeated: it is up to the caller to decide if that is an error.
  617.  
  618.   The character SW appearing alone as the last argument is an error.
  619.   The lead-in sequence SWSW ("--" or "//") causes itself and all the
  620.   rest of the line to be ignored (allowing non-options which begin
  621.   with the switch char).
  622.  
  623.   The string *optionS allows valid opt/arg letters to be recognized.
  624.   argLetters are followed with ':'.  Getopt () returns the value of
  625.   the option character found, or EOF if no more options are in the
  626.   command line.     If option is an argLetter then the global optarg is
  627.   set to point to the argument string (having skipped any white-space).
  628.  
  629.   The global optind is initially 1 and is always left as the index
  630.   of the next argument of argv[] which getopt has not taken.  Note
  631.   that if "--" or "//" are used then optind is stepped to the next
  632.   argument before getopt() returns EOF.
  633.  
  634.   If an error occurs, that is an SW char precedes an unknown letter,
  635.   then getopt() will return a '?' character and normally prints an
  636.   error message via perror().  If the global variable opterr is set
  637.   to false (zero) before calling getopt() then the error message is
  638.   not printed.
  639.  
  640.   For example, if the MSDOS switch char is '/' (the MSDOS norm) and
  641.  
  642.     *optionS == "A:F:PuU:wXZ:"
  643.  
  644.   then 'P', 'u', 'w', and 'X' are option letters and 'F', 'U', 'Z'
  645.   are followed by arguments.  A valid command line may be:
  646.  
  647.     aCommand  /uPFPi /X /A L someFile
  648.  
  649.   where:
  650.     - 'u' and 'P' will be returned as isolated option letters.
  651.     - 'F' will return with "Pi" as its argument string.
  652.     - 'X' is an isolated option.
  653.     - 'A' will return with "L" as its argument.
  654.     - "someFile" is not an option, and terminates getOpt.  The
  655.       caller may collect remaining arguments using argv pointers.
  656. */
  657.  
  658. int    getopt(int argc, char *argv[], char *optionS)
  659. {
  660.     unsigned char ch;
  661.     char *optP;
  662.  
  663.     if (argc > optind) {
  664.         if (letP == NULL) {
  665.             if ((letP = argv[optind]) == NULL ||
  666.                 *(letP++) != SW)  goto gopEOF;
  667.             if (*letP == SW) {
  668.                 optind++;  goto gopEOF;
  669.             }
  670.         }
  671.         if (0 == (ch = *(letP++))) {
  672.             optind++;  goto gopEOF;
  673.         }
  674.         if (':' == ch  ||  (optP = strchr(optionS, ch)) == NULL)  
  675.             goto gopError;
  676.         if (':' == *(++optP)) {
  677.             optind++;
  678.             if (0 == *letP) {
  679.                 if (argc <= optind)  goto  gopError;
  680.                 letP = argv[optind++];
  681.             }
  682.             optarg = letP;
  683.             letP = NULL;
  684.         } else {
  685.             if (0 == *letP) {
  686.                 optind++;
  687.                 letP = NULL;
  688.             }
  689.             optarg = NULL;
  690.         }
  691.         return ch;
  692.     }
  693. gopEOF:
  694.     optarg = letP = NULL;  
  695.     return EOF;
  696.  
  697. gopError:
  698.     optarg = NULL;
  699.     errno  = EINVAL;
  700.     if (opterr)
  701.         perror ("get command line option");
  702.     return ('?');
  703. }
  704.